<template>
  <div
    class="min-h-screen bg-gradient-to-br from-purple-50 via-white to-blue-50 dark:from-gray-900 dark:via-gray-800 dark:to-gray-900 transition-colors duration-300"
  >
    <search-header
      :keyword="keyword"
      @search="search"
      class="mb-2"
    ></search-header>

    <!-- Category Tabs -->
    <div
      class="w-full backdrop-blur-md bg-white/40 dark:bg-gray-800/40 sticky top-0 z-10 shadow-sm transition-all duration-300"
    >
      <div class="max-w-[1240px] mx-auto px-4 py-4">
        <div class="flex flex-col sm:flex-row gap-4">
          <!-- Category Selection -->
          <div class="flex gap-3 transition-all duration-300">
            <el-button
              v-for="(item, index) in categories"
              :key="index"
              :class="[
                'relative transition-all duration-300 rounded-lg transform group',
                category === item.value
                  ? 'shadow-lg !text-white scale-105'
                  : 'hover:scale-105 hover:bg-white/50 dark:hover:bg-gray-600/50',
                category === item.value
                  ? '!bg-gradient-to-r from-purple-500 to-blue-500 hover:from-purple-600 hover:to-blue-600'
                  : '',
              ]"
              :title="item.description"
              type="primary"
              :plain="category !== item.value"
              @click="switchCategory(item.value)"
            >
              <i :class="item.icon" class="mr-2"></i>
              {{ item.label }}
              <span
                v-if="category === item.value"
                class="absolute -top-1 -right-1 flex"
              >
                <span
                  class="animate-ping absolute inline-flex h-2 w-2 rounded-full bg-purple-400 opacity-75"
                ></span>
                <span
                  class="relative inline-flex rounded-full h-2 w-2 bg-purple-500"
                ></span>
              </span>
            </el-button>
          </div>

          <!-- Stats Display with Enhanced Visual -->
          <div
            v-if="category === 'clouddrive' && loadingProgress.isLoading"
            class="flex-1 flex items-center gap-4 bg-white/50 dark:bg-gray-700/50 rounded-lg p-3 transition-all duration-300 backdrop-blur-sm"
          >
            <div class="flex-1 relative">
              <el-progress
                :percentage="
                  Math.round(
                    (loadingProgress.completed / loadingProgress.total) * 100
                  )
                "
                :stroke-width="4"
                :show-text="false"
                class="flex-1"
              >
              </el-progress>
              <div
                class="absolute inset-0 bg-gradient-to-r from-transparent via-white/20 to-transparent animate-shimmer"
              ></div>
            </div>
            <span
              class="text-sm text-purple-600 dark:text-purple-400 font-medium whitespace-nowrap flex items-center gap-2"
            >
              <i class="fas fa-spinner fa-spin"></i>
              搜索中... {{ loadingProgress.completed }}/{{
                loadingProgress.total
              }}
            </span>
          </div>
        </div>
      </div>
    </div>

    <!-- Main Content Area -->
    <div class="mx-auto overflow-y-auto px-4 scroll-smooth">
      <div class="max-w-[1240px] mx-auto">
        <!-- Cloud Drive Content -->
        <transition name="fade" mode="out-in">
          <div class="p-4" v-if="category === 'clouddrive'">
            <div class="transition-all duration-300 space-y-2">
              <disk-info-list
                :sources="sources"
                :skeleton-loading="skeletonLoading"
              >
              </disk-info-list>
            </div>
          </div>
        </transition>

        <!-- VOD Content -->
        <transition name="fade" mode="out-in">
          <div v-if="category === 'onlineVod'" class="p-2">
            <div class="space-y-4">
              <!-- Loading Skeletons -->
              <template
                v-if="
                  vodData.length === 0 &&
                  Array.from(loadingStatus.values()).some((status) => status)
                "
              >
                <!-- Header Skeleton -->
                <div
                  class="flex flex-col sm:flex-row justify-between items-center gap-2 mb-4 px-2 animate-pulse"
                >
                  <div
                    class="h-6 bg-gray-200/50 dark:bg-gray-700/50 rounded-lg w-48"
                  ></div>
                  <div
                    class="h-8 bg-red-100/50 dark:bg-red-900/30 rounded-full w-64"
                  ></div>
                </div>

                <!-- Video Player Skeleton -->
                <div
                  class="relative rounded-xl overflow-hidden bg-black/5 dark:bg-white/5 backdrop-blur-sm"
                >
                  <div
                    class="aspect-video w-full bg-gray-200/50 dark:bg-gray-700/50 animate-pulse"
                  >
                    <div
                      class="absolute inset-0 flex items-center justify-center"
                    >
                      <i
                        class="fas fa-film text-4xl text-gray-400 dark:text-gray-600"
                      ></i>
                    </div>
                  </div>
                </div>

                <!-- Episodes List Skeleton -->
                <div
                  class="grid grid-cols-2 sm:grid-cols-4 lg:grid-cols-6 gap-2 p-2"
                >
                  <div
                    v-for="i in 12"
                    :key="i"
                    class="h-10 bg-gray-200/50 dark:bg-gray-700/50 rounded-lg animate-pulse"
                  ></div>
                </div>
              </template>

              <!-- VOD List -->
              <template v-else>
                <vod-list
                  :vod-data="vodData"
                  class="transition-opacity duration-300"
                  :class="{
                    'opacity-0': Array.from(loadingStatus.values()).some(
                      (status) => status
                    ),
                  }"
                ></vod-list>
              </template>
            </div>
          </div>
        </transition>

        <!-- Soupian iframe -->
        <transition name="fade" mode="out-in">
          <div v-if="category === 'soupian'" class="h-full w-full py-4">
            <div
              class="bg-white/60 dark:bg-gray-800/60 backdrop-blur-lg shadow-sm hover:shadow-lg hover:bg-white/70 dark:hover:bg-gray-800/70 p-5 ring-1 ring-black/5 dark:ring-white/5 transition-all duration-300"
            >
              <div class="relative w-full h-[calc(100vh-240px)]">
                <div
                  v-if="!iframeLoaded"
                  class="absolute inset-0 flex items-center justify-center bg-white/90 dark:bg-gray-800/90 rounded-lg backdrop-blur-sm"
                >
                  <div class="flex flex-col items-center gap-3">
                    <div class="relative w-12 h-12">
                      <div
                        class="absolute inset-0 border-4 border-purple-500/30 rounded-full"
                      ></div>
                      <div
                        class="absolute inset-0 border-4 border-purple-500 border-t-transparent rounded-full animate-spin"
                      ></div>
                    </div>
                    <span
                      class="text-sm text-purple-600 dark:text-purple-400 font-medium"
                      >加载中...</span
                    >
                  </div>
                </div>
                <iframe
                  id="soupian"
                  :src="'https://soupian.pro/frame?movie=' + keyword"
                  class="w-full h-full rounded-lg border-0 bg-white/90 dark:bg-gray-900/90 transition-colors duration-300"
                  loading="lazy"
                  @load="iframeLoaded = true"
                ></iframe>
              </div>
            </div>
          </div>
        </transition>
      </div>

      <!-- Empty State with Enhanced Visual -->
      <div
        v-if="
          !skeletonLoading &&
          !Array.from(loadingStatus.values()).some((status) => status) &&
          ((category === 'clouddrive' && sources.length === 0) ||
            (category === 'onlineVod' && vodData.length === 0))
        "
        class="flex flex-col items-center justify-center py-16 text-gray-500 dark:text-gray-400"
      >
        <div
          class="p-8 rounded-full bg-gradient-to-br from-purple-100/50 to-blue-100/50 dark:from-purple-900/20 dark:to-blue-900/20 mb-6 shadow-lg backdrop-blur-sm group hover:scale-105 transition-all duration-300"
        >
          <i
            class="fas fa-search text-5xl text-purple-500/70 dark:text-purple-400/70 group-hover:rotate-12 transition-transform duration-300"
          ></i>
        </div>
        <h3
          class="text-xl font-semibold bg-gradient-to-r from-purple-600 to-blue-600 bg-clip-text text-transparent"
        >
          未找到相关结果
        </h3>
        <p class="text-sm mt-3 opacity-75">试试以下建议：</p>
        <ul class="mt-4 text-sm space-y-2 text-center">
          <li>• 检查输入是否正确</li>
          <li>• 尝试使用不同的关键词</li>
          <li>• 切换其他分类查找</li>
        </ul>
      </div>

      <!-- Enhanced Backtop -->
      <el-backtop
        :right="24"
        :bottom="24"
        class="!bg-gradient-to-r from-purple-500 to-blue-500 hover:from-purple-600 hover:to-blue-600 !w-12 !h-12 transition-all duration-300 !rounded-xl group hover:scale-110 !shadow-lg hover:!shadow-xl backdrop-blur-sm flex items-center justify-center"
      >
        <i class="fas fa-arrow-up text-white group-hover:animate-bounce"></i>
      </el-backtop>
    </div>
  </div>
</template>

<script setup>
import SearchHeader from "~/components/search/SearchHeader.vue";
import DiskInfoList from "~/components/diskInfoList.vue";
import sourcesApiEndpoints from "~/assets/vod/clouddrive.json";
import { badWords } from "~/utils/sensitiveWords";

definePageMeta({
  layout: "custom",
});

const route = useRoute();
const keyword = ref(decodeURIComponent(route.query.keyword));
const sources = ref([]);
const skeletonLoading = ref(false);
const loadingProgress = ref({
  total: 0,
  completed: 0,
  isLoading: false,
});
const loadingStatus = ref(new Map());

// 智能缓存类
class SmartCache {
  constructor(maxSize = 100, storageKey = "smart_cache_data") {
    this.maxSize = maxSize;
    this.storageKey = storageKey;
    this.cache = new Map();
    this.stats = {
      hits: 0,
      misses: 0,
      total: 0,
    };

    // 初始化时不立即加载数据，而是等待客户端初始化
    if (process.client) {
      this.init();
    }
  }

  // 客户端初始化
  init() {
    // 从localStorage加载缓存数据
    this.loadFromStorage();

    // 定期保存缓存到localStorage
    this.setupAutoSave();

    // 定期清理过期数据
    this.setupCleanupInterval();
  }

  // 从localStorage加载数据
  loadFromStorage() {
    if (!process.client) return;

    try {
      const savedData = localStorage.getItem(this.storageKey);
      if (savedData) {
        const { cache, stats } = JSON.parse(savedData);

        // 恢复缓存数据
        Object.entries(cache).forEach(([key, item]) => {
          // 检查数据是否过期
          if (Date.now() <= item.expiry) {
            this.cache.set(key, item);
          }
        });

        // 恢复统计数据
        this.stats = stats;

        if (process.env.NODE_ENV === "development") {
          console.log("Cache loaded from localStorage:", this.getStats());
        }
      }
    } catch (err) {
      console.error("Error loading cache from localStorage:", err);
      this.clearStorage();
    }
  }

  // 保存数据到localStorage
  saveToStorage() {
    if (!process.client) return;

    try {
      // 将Map转换为普通对象以便序列化
      const cacheObj = {};
      this.cache.forEach((value, key) => {
        cacheObj[key] = value;
      });

      const data = {
        cache: cacheObj,
        stats: this.stats,
        timestamp: Date.now(),
      };

      localStorage.setItem(this.storageKey, JSON.stringify(data));

      if (process.env.NODE_ENV === "development") {
        console.log("Cache saved to localStorage");
      }
    } catch (err) {
      console.error("Error saving cache to localStorage:", err);
      // 如果存储失败（比如超出配额），清理一部分数据后重试
      this.cleanup(true);
      try {
        this.saveToStorage();
      } catch (retryErr) {
        console.error("Failed to save cache even after cleanup:", retryErr);
      }
    }
  }

  // 设置自动保存
  setupAutoSave() {
    if (!process.client) return;

    // 每30秒保存一次
    const saveInterval = setInterval(() => this.saveToStorage(), 30000);

    // 页面关闭时保存
    window.addEventListener("beforeunload", () => {
      this.saveToStorage();
      clearInterval(saveInterval);
    });
  }

  // 设置定期清理
  setupCleanupInterval() {
    if (!process.client) return;

    // 每5分钟清理一次过期数据
    const cleanupInterval = setInterval(() => this.cleanup(), 5 * 60 * 1000);

    // 页面关闭时清理定时器
    window.addEventListener("beforeunload", () => {
      clearInterval(cleanupInterval);
    });
  }

  // 清理localStorage中的缓存数据
  clearStorage() {
    if (!process.client) return;

    try {
      localStorage.removeItem(this.storageKey);
      if (process.env.NODE_ENV === "development") {
        console.log("Cache storage cleared");
      }
    } catch (err) {
      console.error("Error clearing cache storage:", err);
    }
  }

  // 获取缓存命中率
  getHitRate() {
    return this.stats.total === 0
      ? 0
      : ((this.stats.hits / this.stats.total) * 100).toFixed(2);
  }

  // 动态计算缓存时间
  getDynamicTTL(key, value) {
    const baseTime = 5 * 60 * 1000; // 基础5分钟
    const hitRate = this.getHitRate();

    // 根据数据大小调整缓存时间
    const sizeMultiplier = Array.isArray(value)
      ? Math.min(1, 10 / value.length)
      : 1;

    // 根据命中率调整缓存时间
    const hitRateMultiplier = hitRate > 80 ? 1.5 : 1;

    // 根据访问频率调整
    const accessCount = this.getAccessCount(key);
    const frequencyMultiplier = Math.min(2, 1 + accessCount * 0.1);

    return Math.floor(
      baseTime * sizeMultiplier * hitRateMultiplier * frequencyMultiplier
    );
  }

  // 获取键的访问次数
  getAccessCount(key) {
    const item = this.cache.get(key);
    return item ? item.accessCount || 0 : 0;
  }

  // 检查是否需要清理缓存
  cleanup(force = false) {
    // 计算存储使用情况
    const storageUsed = localStorage.length;
    const storageLimit = 5 * 1024 * 1024; // 5MB限制

    // 如果强制清理或缓存大小超出限制
    if (force || this.cache.size > this.maxSize || storageUsed > storageLimit) {
      const entries = Array.from(this.cache.entries()).sort((a, b) => {
        const scoreA = a[1].lastAccessed * (a[1].accessCount || 1);
        const scoreB = b[1].lastAccessed * (b[1].accessCount || 1);
        return scoreA - scoreB;
      });

      // 删除最不常用的数据
      const deleteCount = Math.max(
        Math.floor(this.maxSize * 0.25),
        Math.floor(entries.length * 0.25)
      );

      entries.slice(0, deleteCount).forEach(([key]) => {
        this.cache.delete(key);
      });

      // 保存更新后的缓存
      this.saveToStorage();

      if (process.env.NODE_ENV === "development") {
        console.log(`Cleaned up ${deleteCount} cache entries`);
      }
    }
  }

  // 获取缓存数据
  get(key) {
    this.stats.total++;
    const item = this.cache.get(key);

    if (!item) {
      this.stats.misses++;
      return null;
    }

    // 检查是否过期
    if (Date.now() > item.expiry) {
      this.cache.delete(key);
      this.stats.misses++;
      return null;
    }

    this.stats.hits++;
    item.lastAccessed = Date.now();
    item.accessCount = (item.accessCount || 0) + 1;
    return item.value;
  }

  // 设置缓存数据
  set(key, value) {
    const ttl = this.getDynamicTTL(key, value);

    this.cache.set(key, {
      value,
      expiry: Date.now() + ttl,
      lastAccessed: Date.now(),
      accessCount: 1,
      size: JSON.stringify(value).length, // 记录数据大小
    });

    this.cleanup();

    // 异步保存到localStorage
    setTimeout(() => this.saveToStorage(), 0);
  }

  // 获取缓存统计信息
  getStats() {
    const totalSize = Array.from(this.cache.values()).reduce(
      (sum, item) => sum + (item.size || 0),
      0
    );

    return {
      ...this.stats,
      hitRate: this.getHitRate(),
      size: this.cache.size,
      maxSize: this.maxSize,
      totalSize: `${(totalSize / 1024).toFixed(2)}KB`,
      storageUsed: `${(localStorage.length / 1024).toFixed(2)}KB`,
    };
  }
}

// 创建智能缓存实例
const smartCache = new SmartCache(100, "aipan_search_cache");

// 在组件挂载后初始化缓存系统
onMounted(() => {
  if (process.client) {
    smartCache.init();
  }
});

// 添加请求超时控制函数
const fetchWithTimeout = async (url, options, timeout = 5000) => {
  const controller = new AbortController();
  const timeoutId = setTimeout(() => controller.abort(), timeout);

  try {
    const response = await $fetch(url, {
      ...options,
      signal: controller.signal,
    });
    return response;
  } finally {
    clearTimeout(timeoutId);
  }
};

// 添加并发控制
const concurrentLimit = 3;
const queue = [];
let running = 0;

const runQueue = async () => {
  if (queue.length === 0 || running >= concurrentLimit) return;

  running++;
  const task = queue.shift();
  try {
    await task();
  } finally {
    running--;
    runQueue();
  }
};

// 优化重试机制
const fetchWithRetry = async (url, options, retries = 1) => {
  for (let i = 0; i < retries + 1; i++) {
    try {
      return await fetchWithTimeout(url, options);
    } catch (error) {
      if (i === retries) throw error;
      await new Promise((resolve) => setTimeout(resolve, 500));
    }
  }
};

// 处理单个API的搜索
const handleSingleSearch = async (item) => {
  const cacheKey = `${item.api}-${keyword.value}`;

  const task = async () => {
    try {
      const cachedData = smartCache.get(cacheKey);
      if (cachedData) {
        sources.value.push(...cachedData);
        loadingProgress.value.completed++;
        return;
      }

      const res = await fetchWithRetry(item.api, {
        method: "POST",
        body: {
          name: keyword.value,
        },
      });

      if (res.list && res.list.length) {
        smartCache.set(cacheKey, res.list);
        sources.value.push(...res.list);
      }
    } catch (err) {
      console.error(`Error fetching from ${item.api}:`, err);
    } finally {
      loadingProgress.value.completed++;
      if (loadingProgress.value.completed >= loadingProgress.value.total) {
        loadingProgress.value.isLoading = false;
      }
    }
  };

  queue.push(task);
  runQueue();
};

const handleSearch = async () => {
  sources.value = [];
  queue.length = 0;
  running = 0;

  // 重置加载进度
  loadingProgress.value = {
    total: sourcesApiEndpoints.length,
    completed: 0,
    isLoading: true,
  };

  sourcesApiEndpoints.forEach((item) => {
    handleSingleSearch(item);
  });
};

// VOD搜索的单个处理函数
const handleSingleVodSearch = async (vodApi) => {
  const cacheKey = `vod-${vodApi.api}-${keyword.value}`;
  loadingStatus.value.set(vodApi.api, true);

  try {
    const cachedData = smartCache.get(cacheKey);
    if (cachedData) {
      vodData.value = [...vodData.value, ...cachedData];
      loadingStatus.value.set(vodApi.api, false);
      return;
    }

    const res = await fetchWithRetry("/api/vod/search", {
      method: "get",
      query: {
        type: vodApi.type,
        api: vodApi.api,
        ac: "detail",
        wd: keyword.value,
      },
    });

    if (res.code !== 500 && res.list && res.list.length) {
      const processedData = res.list.map((item) =>
        Object.assign(
          { playUrl: vodApi.playUrl, sourceName: vodApi.name },
          item
        )
      );
      smartCache.set(cacheKey, processedData);
      vodData.value = [...vodData.value, ...processedData];
    }
  } catch (err) {
    console.error(`Error fetching VOD from ${vodApi.api}:`, err);
  } finally {
    loadingStatus.value.set(vodApi.api, false);
  }
};

const searchByVod = async () => {
  vodData.value = [];

  vodApiEndpoints.forEach((vodApi) => {
    loadingStatus.value.set(vodApi.api, false);
  });

  vodApiEndpoints.forEach((vodApi) => {
    handleSingleVodSearch(vodApi);
  });
};

const search = (e) => {
  if (badWords.includes(e)) {
    return alert("请勿输入敏感词");
  }
  keyword.value = e;
  skeletonLoading.value = false;
  sources.value = [];
  handleSearch();
};

const colorMode = useColorMode();
const category = ref("clouddrive");

import vodApiEndpoints from "~/assets/vod/list";

const vodData = ref([]);

const iframeLoaded = ref(false);

const switchCategory = (e) => {
  category.value = e;
  iframeLoaded.value = false;
  if (e === "clouddrive") {
    sources.value = [];
    handleSearch();
  } else if (e === "onlineVod") {
    vodData.value = [];
    searchByVod();
  }
};

onMounted(() => {
  if (keyword.value) {
    handleSearch();
  }
});

// 定义分类选项
const categories = [
  {
    value: "clouddrive",
    label: "网盘资源",
    icon: "fas fa-cloud",
    description: "搜索各大网盘资源",
  },
  {
    value: "onlineVod",
    label: "在线观影",
    icon: "fas fa-film",
    description: "搜索在线视频资源",
  },
  {
    value: "soupian",
    label: "搜片",
    icon: "fas fa-video",
    description: "专业影视搜索引擎",
  },
];
</script>

<style scoped>
/* Enhanced button styles */
.el-button {
  @apply font-medium border-none shadow-sm hover:shadow-md relative overflow-hidden;
  transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
}

.el-button:hover {
  transform: translateY(-1px);
}

.el-button::after {
  content: "";
  @apply absolute inset-0 bg-gradient-to-r from-white/0 via-white/20 to-white/0 -translate-x-full;
  transition: transform 0.6s ease;
}

.el-button:hover::after {
  transform: translateX(100%);
}

/* Enhanced loading animations */
@keyframes gradient {
  0% {
    background-position: 0% 50%;
  }
  50% {
    background-position: 100% 50%;
  }
  100% {
    background-position: 0% 50%;
  }
}

:deep(.el-progress-bar__inner) {
  @apply bg-gradient-to-r from-purple-500 via-blue-500 to-purple-500 transition-all duration-300;
  background-size: 200% 100%;
  animation: gradient 2s ease infinite;
}

:deep(.el-progress-bar__outer) {
  @apply bg-gray-100/50 dark:bg-gray-700/50 rounded-full overflow-hidden;
  backdrop-filter: blur(4px);
}

/* Enhanced transitions */
.fade-enter-active,
.fade-leave-active {
  transition:
    opacity 0.4s cubic-bezier(0.4, 0, 0.2, 1),
    transform 0.4s cubic-bezier(0.4, 0, 0.2, 1);
}

.fade-enter-from,
.fade-leave-to {
  opacity: 0;
  transform: translateY(10px) scale(0.98);
}

/* Custom scrollbar */
::-webkit-scrollbar {
  @apply w-1.5 h-1.5;
}

::-webkit-scrollbar-track {
  @apply bg-transparent;
}

::-webkit-scrollbar-thumb {
  @apply bg-gradient-to-b from-purple-400/40 to-blue-400/40 rounded-full 
         hover:from-purple-500/50 hover:to-blue-500/50 transition-colors duration-200;
}

/* Enhanced shimmer effect */
@keyframes shimmer {
  0% {
    transform: translateX(-100%) skewX(-15deg);
  }
  100% {
    transform: translateX(100%) skewX(-15deg);
  }
}

.animate-shimmer {
  animation: shimmer 2s infinite;
}

/* Pulse animation with smoother transition */
@keyframes pulse {
  0%,
  100% {
    opacity: 1;
  }
  50% {
    opacity: 0.5;
  }
}

.animate-pulse {
  animation: pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite;
}

/* Enhanced hover effects */
.hover\:shadow-lg {
  --tw-shadow: 0 10px 15px -3px rgb(0 0 0 / 0.1),
    0 4px 6px -4px rgb(0 0 0 / 0.1);
  --tw-shadow-colored: 0 10px 15px -3px var(--tw-shadow-color),
    0 4px 6px -4px var(--tw-shadow-color);
  transition: box-shadow 0.3s cubic-bezier(0.4, 0, 0.2, 1);
}

.dark .hover\:shadow-lg {
  --tw-shadow-color: rgba(0, 0, 0, 0.25);
}

/* Card transitions */
.scale-enter-active,
.scale-leave-active {
  transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1);
}

.scale-enter-from,
.scale-leave-to {
  opacity: 0;
  transform: scale(0.95) translateY(10px);
}
</style>
